<template>
  <div class="dem-handle" v-loading="loading">
    <div class="handle-box">
      <el-form label-width="120px" :inline="false" size="normal">
        <el-row :gutter="20">
          <el-col :span="12">
            <p class="title">DEM/DSM切片</p>
            <el-form-item label="输入路径">
              <el-input v-model="inputPath" size="mini" style="width: calc(100% - 50px)" disabled></el-input>
              <el-button size="mini" @click="openFiles('inputPath')">···</el-button>
            </el-form-item>
            <el-form-item label="输出路径">
              <el-input v-model="outputPath" size="mini" style="width: calc(100% - 50px)" disabled></el-input>
              <el-button size="mini" @click="openFiles('outputPath')">···</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <p class="title">轻量化参数选项</p>
            <el-form-item label="最大层级">
              <el-input v-model.number="endLevel" size="mini" style="width: 45%"></el-input>
            </el-form-item>
            <el-form-item label="压缩格式">
              <el-select v-model="compressedFormat" size="mini">
                <el-option label="terrain" value="terrain">terrain</el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-progress :text-inside="true" :stroke-width="26" :percentage="percentage" v-show="progressShow"></el-progress>
      <div class="start-processing">
        <el-button type="primary" size="mini" @click="startProcessing">开始处理</el-button>
      </div>
    </div>
    <!-- 输入选择 -->
    <el-dialog title="选择文件夹" :visible.sync="inputFilesShow" width="30%" @close="deselect" :destroy-on-close="true"
      :close-on-click-modal="false" v-loading="loading">
      <div class="file-box" v-loading="fileLoading">
        <el-scrollbar style="height:calc(100% - 30px);">
          <el-tree :props="props" :load="loadImageNode" lazy :expand-on-click-node="false" @node-click="imageSelect">
          </el-tree>
        </el-scrollbar>
        <el-input v-model="folderAddress" size="mini" disabled></el-input>
      </div>
      <span slot="footer">
        <el-button @click="deselect">Cancel</el-button>
        <el-button type="primary" @click="confirmClick">确定</el-button>
      </span>
    </el-dialog>
    <!-- 输出选择 -->
    <el-dialog title="选择文件夹" :visible.sync="fileSelectShow" width="30%" @close="deselect" :destroy-on-close="true"
      :close-on-click-modal="false">
      <div class="file-box" v-loading="fileLoading">
        <el-scrollbar style="height:calc(100% - 30px);">
          <el-tree :props="props" :load="loadFileNode" lazy :expand-on-click-node="false" @node-click="selectFile">
          </el-tree>
        </el-scrollbar>
        <el-input v-model="folderAddress" size="mini" disabled></el-input>
      </div>
      <span slot="footer">
        <el-button @click="deselect">取消</el-button>
        <el-button type="primary" @click="definiteSelect">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  data () {
    return {
      datasourceId: '',
      progressShow: false,
      percentage: 0,
      timer: null,
      loading: false,
      inputPath: '',
      outputPath: '',
      inputFilesShow: false,
      props: {
        label: 'name',
        children: 'children',
        isLeaf: 'leaf'
      },
      fileSelectShow: false,
      fileLoading: false,
      folderAddress: '',
      startLevel: 1,
      endLevel: 20,
      selectNode: null,
      questId: '',
      compressedFormat: "terrain",
      defaultLevels: [],
      fileGroup: [],
      cacheConfig: { "needImgCache": false, "imgCacheMode": 1, "imgCacheLevel": [0, 20] },
      center: { "x": 111.36480081860076, "y": 26.095331959088416, "height": 5000, "heading": "0", "pitch": "-90", "roll": "0" },
      config: { "images": [], "terrain": true, "bands": [], "srid": 4326, "noDataValue": [], "resampleConfigs": [], "dispelEdgedConfigs": [], "render": [], "grid": "", "programme": 0, "origin": null, "resolutions": null, "styleJson": {}, "imgMap": { "/data/raster/HN_DEM_30m/HN_DEM_30m.tif": { "rasterEditable": { "bandslndex": [1], "bandsIndexNoDataValue": [0] }, "fileSize": 0 } }, "gridUnit": 1 },
    };
  },
  methods: {
    async startProcessing () {
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
      if (!this.inputPath || !this.outputPath) {
        this.$message.error("请先选择输入路径和输出路径")
        return
      }
      // let usableDataSource = await this.getDataSource()
      this.config.imgMap = {}
      this.config.styleJson = {}
      if (this.fileGroup.length == 0) {
        this.config.images = [
          {
            img: this.selectNode.data.path,
            datasourceId: this.datasourceId
          }
        ]
        this.config.bands = this.selectNode.data.bands
        this.config.srid = this.selectNode.data.srid
        this.config.noDataValue = this.selectNode.data.noDataValue
        this.config.styleJson[`1-${this.endLevel}`] = {
          fileNameList: [this.selectNode.data.path]
        }
        this.config.imgMap[this.selectNode.data.path] = {
          rasterEditable: {
            bandslndex: this.selectNode.data.bands,
            bandsIndexNoDataValue: this.selectNode.data.noDataValue
          },
          fileSize: 0
        }
        let x = (this.selectNode.data.bbox[0] + this.selectNode.data.bbox[2]) / 2
        let y = (this.selectNode.data.bbox[1] + this.selectNode.data.bbox[3]) / 2
        this.center.x = x
        this.center.y = y
      } else {
        this.config.imgMap = {}
        this.config.styleJson = {}
        this.config.bands = this.fileGroup[0].bands
        this.config.srid = this.fileGroup[0].srid
        this.config.noDataValue = this.fileGroup[0].noDataValue
        let x = (this.fileGroup[0].bbox[0] + this.fileGroup[0].bbox[2]) / 2
        let y = (this.fileGroup[0].bbox[1] + this.fileGroup[0].bbox[3]) / 2
        this.center.x = x
        this.center.y = y
        this.fileGroup.forEach(item => {
          this.config.images.push({
            img: item.path,
            datasourceId: this.datasourceId
          })
          this.config.imgMap[item.path] = {
            rasterEditable: {
              bandslndex: item.bands,
              bandsIndexNoDataValue: item.noDataValue
            },
            fileSize: 0
          }
          let level = `1-${this.endLevel}`
          if (!this.config.styleJson[level]) {
            this.config.styleJson[level] = {
              fileNameList: []
            }
          }
          this.config.styleJson[level].fileNameList.push(item.path)
        })
      }
      let params = {
        cacheConfig: JSON.stringify(this.cacheConfig),
        center: JSON.stringify(this.center),
        config: JSON.stringify(this.config),
        datasourceId: '',
        groupId: "-3",
        name: "测评地形_" + new Date().getTime(),
        type: 3
      }
      this.loading = true
      let res = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/register`, [params])
      setTimeout(() => {
        this.loading = false
        this.getServiceInfo(res.data.data[0])
      }, 3000)
    },
    // 获取地形服务详情并存储
    async getServiceInfo (id) {
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/dataservice/getInfo/${id}`)
      let info = res.data.data
      this.questId = info.id
      let params = {
        id: info.id,
        name: info.name,
        info: JSON.stringify(info),
        path: this.outputPath,
        // 0: DEM 1：DOM 
        type: 0
      }
      await axios.post(`${window.nodeApiIp}/saveService/insertDemService`, params)
      let resp = await axios.post(`${window.nodeApiIp}/dataExport/terrainExport`, {
        id: info.id,
        name: info.name,
        src: this.outputPath
      })
      if (resp.data.status == 200) {
        this.$message.success(resp.data.msg)
        this.progressShow = true
        this.timer = setInterval(() => {
          axios.get(`${window.nodeApiIp}/saveService/getInfoById?id=${info.id}`).then(res => {
            this.percentage = (parseFloat(res.data[0].scale)).toFixed(2) - 0
            if (res.data[0].scale == '100') {
              clearInterval(this.timer)
              this.timer = null
              this.$message.success('转换成功')
              setTimeout(() => {
                this.$router.go(0)
              }, 2000)
            }
          })
        }, 3000)
      }
    },
    // 获取最优层级
    async getBestLevels (path) {
      let rasterData = await axios.get(`${window.mapServerIp}/rasterserver/raster/getRasterInfo?path=${encodeURIComponent(path)}`)
      this.fileGroup.push(this.getRasterData(rasterData.data))
      let res = await axios.post(`${window.mapServerIp}/rasterserver/raster/getFitLevels`, {
        path: path,
        gridName: "degreebase256tdt"
      })
      this.defaultLevels = []
      let levels = res.data.data.levels
      let level = `${levels[0].level}-${levels[levels.length - 1].level}`
      this.startLevel = levels[0].level
      this.endLevel = levels[levels.length - 1].level
      this.defaultLevels.push(level)
    },
    // 处理栅格文件信息
    getRasterData (data) {
      let obj = {
        "path": data.file,
        "srid": data.srid - 0,
        "bbox": data.bbox,
        "noDataValue": [
          data.noDataValueEachChannel
        ],
        "bands": data.bandsIndex,
      }
      return obj
    },
    // 获取所有影像服务源并查找符合输入路径的数据源
    async getDataSource () {
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/list?typeCode=0103&page=1&rows=10000`)
      let usableDataSource = res.data.data.records.filter(item => this.inputPath.indexOf(item.config) > -1)
      return usableDataSource
    },
    // 查询数据源中是否存在当前路径，没有的话创建数据源
    async createDataSource (path) {
      let isWindowsPath = /^[A-Za-z]:\\/
      let isLinuxPath = /^\/[^/]+/
      let config = ''
      if (isWindowsPath.test(path)) {
        let arr = path.split('\\')
        arr.forEach((item, index) => {
          if (index < arr.length - 1) {
            config += item + '\\'
          }
        })
      }
      if (isLinuxPath.test(path)) {
        let arr = path.split('/')
        arr.forEach((item, index) => {
          if (index < arr.length - 1) {
            config += item + '/'
          }
        })
      }
      let res = await axios.post(`${window.mapServerIp}/${window.prefix}/datasource/register`, {
        config: config,
        name: "测试" + new Date().getTime(),
        password: "",
        remark: "",
        type: "raster",
        typeCode: "0103",
        user: ""
      })
      if (res.data.status !== 200) {
        this.$message.success('数据创建失败')
      }
    },
    async confirmClick () {
      this.loading = true
      this.fileGroup = []
      this.inputPath = this.folderAddress
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/list?typeCode=0103&page=1&rows=10000`)
      if (res.data.data.records.length > 0) {
        let usableDataSource = res.data.data.records.filter(item => this.inputPath.indexOf(item.config) > -1)
        if (!usableDataSource.length) {
          this.$message.warning('当前路径不在已配置文件夹下,请添加配置')
          return
        } else {
          await axios.get(`${window.mapServerIp}/${window.prefix}/timer/checkRasterDataSource`)
          this.datasourceId = usableDataSource[0].idString
          let fileList = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getList?path=${encodeURIComponent(usableDataSource[0].config)}&page=1&rows=10000`)
          if (this.selectNode.leaf) {
            for (let i = 0; i < fileList.data.data.list.length; i++) {
              const element = fileList.data.data.list[i];
              if (element.path == this.inputPath) {
                // 判断坐标系是否满足条件，不满足需要进行转换
                if (element.srid == 4490 || element.srid == 4326) {
                  // this.getBestLevels(this.inputPath)
                  this.getAllImageTif([this.inputPath])
                } else {
                  let urlList = await this.convertFile([element.path])
                  // this.getBestLevels(urlList[0])
                  this.getAllImageTif(urlList)
                  break
                }
              }
            }
          } else {
            let primitivePath = []
            let urlList = []
            for (let i = 0; i < fileList.data.data.list.length; i++) {
              const element = fileList.data.data.list[i];
              let elePath = element.path
              let str = ''
              elePath.split('\\').slice(0, -1).forEach(j => {
                str += j + '\\'
              })
              str = str.slice(0, -1)
              if (this.inputPath == str) {
                if (element.srid == 4490 || element.srid == 4326) {
                  urlList.push(elePath)
                } else {
                  primitivePath.push(elePath)
                }
              }
            }
            primitivePath = [...new Set(primitivePath)]
            if (primitivePath.length > 0) {
              let arr = await this.convertFile(primitivePath)
              arr.forEach(item => {
                urlList.push(item.path)
              })
            }
            this.getAllImageTif(urlList)
          }
        }
      }
      this.inputFilesShow = false
      this.loading = false
    },
    // 坐标系不满足，对文件进行转换
    async convertFile (pathArr) {
      let res = await axios.post(`${window.nodeApiIp}/fileConver/projectToWGS84`, {
        inputPathArr: pathArr
      })
      let pyramids = []
      if (res.data.status == '200') {
        if (res.data.data.length == 0) {
          return []
        }
        await axios.get(`${window.mapServerIp}/${window.prefix}/timer/checkRasterDataSource`)
        return res.data.data
        let pyramidPath = []
        if (res.data.data.length > 0) {
          let path = ''
          let arr = res.data.data[0].path.split('\\')
          arr.forEach((item, index) => {
            if (index < arr.length - 1) {
              path += item + '\\'
            }
          })
          path = path.slice(0, -1)
          let imageFiles = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getImageFile?path=${encodeURIComponent(path)}&page=1&rows=10000`)
          let files = imageFiles.data.data.list
          res.data.data.forEach(i => {
            let file = files.filter(j => j.path == i.path)[0]
            if (file) {
              if (!file.hasPyramid) {
                pyramidPath.push(file.path)
                // pyramids.push(axios.get(`${window.mapServerIp}/${window.prefix}/services/buildPyramid?path=${encodeURIComponent(file.path)}`))
              }
            }
          })
        }
        if (pyramidPath.length > 0) {
          await axios.post(`${window.rasterServerIp}/mapserver/raster/pyramid/batch/build`, {
            path: pyramidPath
          })
          return res.data.data
        }
        if (pyramids.length == 0) {
          return res.data.data
        }
        let k = await Promise.all(pyramids)
        // 获取创建金字塔任务id
        let questIds = []
        k.forEach(m => {
          questIds.push(m.data.data)
        })
        if (questIds.length > 0) {
          return new Promise(async (resolve, reject) => {
            let exist = await this.getQuests(questIds)
            if (exist) {
              let timer = setInterval(async () => {
                exist = await this.getQuests(questIds)
                if (!exist) {
                  clearInterval(timer)
                  resolve(res.data.data)
                }
              }, 2000)
            } else {
              resolve(res.data.data)
            }
          });
        } else {
          return res.data.data
        }
      }
    },
    // 获取正在进行的任务，查看对应id的任务是否都完成
    async getQuests (ids) {
      let exist = false
      let quests = await axios.get(`${window.mapServerIp}/${window.prefix}/services/task-list?status=1`)
      for (let i = 0; i < quests.data.data.records.length; i++) {
        let quest = quests.data.data.records[i]
        let exist = ids.some(id => id == quest.id)
        if (exist) {
          return exist
        }
      }
      return exist
    },
    imageSelect (row) {
      this.selectNode = row
      this.folderAddress = row.path
    },
    // 获取文件夹下所有tif文件，并找到整体的最优层级
    async getAllImageTif (pathList) {
      this.fileGroup = []
      if (pathList.length > 0) {
        this.loading = true
        let path = ''
        let arr = pathList[0].split('\\')
        arr.forEach((item, index) => {
          if (index < arr.length - 1) {
            path += item + '\\'
          }
        })
        let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getImageFile?path=${encodeURIComponent(path)}&page=1&rows=10000`)
        let files = res.data.data.list
        let pyramidPath = []
        pathList.forEach(item => {
          let file = files.filter(i => i.path == item)[0]
          if (file) {
            if (!file.hasPyramid) {
              pyramidPath.push(file.path)
            }
          }
          if (file) {
            this.fileGroup.push(file)
          }
        })
        if (pyramidPath.length > 0) {
          await axios.post(`${window.rasterServerIp}/mapserver/raster/pyramid/batch/build`, {
            path: pyramidPath
          })
        }
        this.config.imgMap = {}
        this.config.styleJson = {}
        this.config.bands = this.fileGroup[0].bands
        this.config.srid = this.fileGroup[0].srid
        this.config.noDataValue = this.fileGroup[0].noDataValue
        let x = (this.fileGroup[0].bbox[0] + this.fileGroup[0].bbox[2]) / 2
        let y = (this.fileGroup[0].bbox[1] + this.fileGroup[0].bbox[3]) / 2
        this.center.x = x
        this.center.y = y
        this.fileGroup.forEach(item => {
          this.config.images.push({
            img: item.path,
            datasourceId: this.datasourceId
          })
          this.config.imgMap[item.path] = {
            rasterEditable: {
              bandslndex: item.bands,
              bandsIndexNoDataValue: item.noDataValue
            },
            fileSize: 0
          }
          let level = `1-${this.endLevel}`
          if (!this.config.styleJson[level]) {
            this.config.styleJson[level] = {
              fileNameList: []
            }
          }
          this.config.styleJson[level].fileNameList.push(item.path)
        })
        let params = {
          config: JSON.stringify(this.config),
          datasourceId: '',
          gridUnit: '',
          name: "",
          type: 3
        }
        let tempRes = await axios.post(`${window.mapServerIp}/${window.prefix}/dataservice/createTemp`, params)
        let fitLevelData = await axios.get(`${window.rasterServerIp}/mapserver/terrain/getFitLevels/${tempRes.data.data}`)
        console.log(fitLevelData)
        this.startLevel = fitLevelData.data[0]
        this.endLevel = fitLevelData.data[1]
        this.defaultLevels = []
        this.defaultLevels.push(`${this.startLevel}-${this.endLevel}`)
        this.loading = false
      }
    },
    openFiles (field) {
      this.folderAddress = ""
      if (field == 'inputPath') {
        this.inputFilesShow = true
      } else {
        this.fileSelectShow = true
      }
    },
    deselect () {
      this.inputFilesShow = false
      this.fileSelectShow = false
    },
    // 获取输入路径
    async loadImageNode (node, resolve) {
      if (node.level === 0) {
        let records = await this.getDisk()
        return resolve(records)
      } else {
        let path = this.getPathFromTree(node)
        let records = await this.getDirectory(path, 'tif,img')
        if (records) {
          return resolve(records)
        } else {
          node.data.leaf = true
          return resolve([])
        }
      }
    },

    // 获取影像文件夹
    async getImageDirectory (path = '') {
      this.loading = true
      let res = await axios.get(`${window.mapServerIp}/${window.prefix}/datasource/getImageFile?path=${path}&rows=10000`)
      this.loading = false
      if (res.data.data.list.length > 0) {
        let fileList = []
        res.data.data.list.forEach(item => {
          let ob = {
            name: item.name,
            path: item.path,
            children: [],
            data: item,
            leaf: item.file
          }
          fileList.push(ob)
        })
        return fileList
      } else {
        return []
      }
    },
    // 获取输出路径
    async loadFileNode (node, resolve) {
      if (node.level === 0) {
        let records = await this.getDisk()
        return resolve(records)
      } else {
        let path = this.getPathFromTree(node)
        let records = await this.getDirectory(path)
        if (records) {
          return resolve(records)
        } else {
          node.data.leaf = true
          return resolve([])
        }
      }
    },
    // 从树中获取到文件路径
    getPathFromTree (node) {
      let path = ''
      if (node.parent.data) {
        let parentPath = this.getPathFromTree(node.parent)
        path = parentPath + node.data.name + "\\"
      } else {
        path = node.data.name + ":\\"
      }
      return path
    },
    // 获取盘符
    async getDisk () {
      this.fileLoading = true
      let res = await axios.get(`${window.nodeApiIp}/directory/driveLetters`)
      this.fileLoading = false
      let fileList = []
      res.data.forEach(item => {
        let ob = {
          name: item,
          children: [],
          path: item,
          leaf: false
        }
        fileList.push(ob)
      })
      return fileList
    },
    // 获取文件夹
    async getDirectory (path, fileType = '') {
      let res = await axios.post(`${window.nodeApiIp}/directory/getDirectory`, {
        path: path,
        fileType: fileType
      })
      if (res.data.directory.length > 0) {
        let fileList = []
        res.data.directory.forEach(item => {
          let ob = {
            name: item.name,
            path: item.path + item.name,
            children: [],
            leaf: false
          }
          if (item.type == 'file') {
            ob.leaf = true
          }
          fileList.push(ob)
        })
        return fileList
      } else {
        return false
      }
    },
    // 获取文件夹地址
    selectFile (data, node) {
      let path = this.getPathFromTree(node)
      this.folderAddress = path
    },
    definiteSelect () {
      this.fileSelectShow = false
      this.outputPath = this.folderAddress
    }
  },
  created () { },
  mounted () { }
};
</script>
<style lang="less">
.dem-handle {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  .handle-box {
    width: 1200px;
    background: rgba(4, 11, 20, 0.63);
    border: 1px solid rgba(22, 93, 202, 0.6);
    border-radius: 10px;
    padding: 10px 30px;
    box-sizing: border-box;

    .title {
      color: #fff;
    }

    .el-form-item__label {
      color: #fff
    }

    .footer {
      width: 100%;
      height: 50px;
      display: flex;
      justify-content: end;
      align-items: center;
    }

    .start-processing {
      width: 100%;
      height: 40px;
      display: flex;
      justify-content: end;
      align-items: center;
    }
  }

  .file-box {
    width: 100%;
    height: 400px
  }
}
</style>